package com.briup.cms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.briup.cms.common.exception.CmsException;
import com.briup.cms.common.model.entity.Article;
import com.briup.cms.common.model.entity.Category;
import com.briup.cms.common.model.entity.User;
import com.briup.cms.common.model.ext.CategoryExt;
import com.briup.cms.common.util.PageUtil;
import com.briup.cms.common.util.ResultCode;
import com.briup.cms.dao.ArticleMapper;
import com.briup.cms.dao.CategoryMapper;
import com.briup.cms.dao.UserMapper;
import com.briup.cms.service.CategoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.management.Descriptor;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * @author YuYan
 * @date 2024-01-09 19:43:02
 */
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {
   private final UserMapper userMapper;
    private final CategoryMapper categoryMapper;
    private  final ArticleMapper articleMapper;
    @Override
    public void save(CategoryExt categoryExt) {
        String name = categoryExt.getName();
        String description = categoryExt.getDescription();
        Integer orderNum = categoryExt.getOrderNum();
        Integer parentId = categoryExt.getParentId();
        LambdaQueryWrapper<Category> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Category::getName,name);
        if(categoryMapper.selectOne(lqw)!=null){
            throw new CmsException(ResultCode.CATEGORY_HAS_EXISTED);
        }
        Category category=new Category();
        category.setName(name);
        category.setDescription(description);
        category.setOrderNum(orderNum);
        category.setParentId(parentId);
        category.setDeleted(0);
        categoryMapper.insert(category);

    }

    @Override
    public void delete(List<Integer> ids) {

        int deletedCount = 0;

        for (Integer id : ids) {
            Category category = categoryMapper.selectById(id);
            if (category.getParentId() == null) {

                LambdaQueryWrapper<Category> lqw = new LambdaQueryWrapper<>();
                lqw.eq(Category::getParentId, id);
                List<Category> categories = categoryMapper.selectList(lqw);
                if (categories == null || categories.size() == 0) {
                    deletedCount += categoryMapper.deleteById(id);
                }
            } else {

                LambdaQueryWrapper<Article> lqw = new LambdaQueryWrapper<>();
                lqw.eq(Article::getCategoryId, id);
                List<Article> articles = articleMapper.selectList(lqw);
                boolean deleted = true;
                if (articles != null) {
                    for (Article article : articles) {

                        Long userId = article.getUserId();

                        User user = userMapper.selectById(userId);

                        if (user.getDeleted().equals(0)) {
                            deleted = false;

                            break;
                        }
                    }
                }

                if (deleted) {
                    deletedCount += categoryMapper.deleteById(id);
                }
            }
        }

        if (deletedCount == 0) {
            throw new CmsException(ResultCode.CATEGORY_DELETE_FAILED);
        }
    }

    @Override
    public void update(CategoryExt categoryExt) {
        Integer id = categoryExt.getId();
        String name = categoryExt.getName();
        String descriptor = categoryExt.getDescription();
        Integer orderNum = categoryExt.getOrderNum();
        Integer parentId = categoryExt.getParentId();
        LambdaQueryWrapper<Category> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Category::getName,name);
        Category record=categoryMapper.selectOne(lqw);
        if(record!=null&&!record.getId().equals(id)){
            throw  new CmsException(ResultCode.CATEGORY_NAME_HAS_EXISTED);
        }
        record=categoryMapper.selectById(id);
        if(record.getParentId()==null&&parentId!=null){
            throw  new CmsException(ResultCode.CATEGORY_EXCEL_CONTENT_ERROR);
        }
        Category category=new Category();
        category.setId(id);
        category.setName(name);
        category.setDescription(descriptor);
        category.setOrderNum(orderNum);
        category.setParentId(parentId);
        categoryMapper.updateById(category);

    }

    @Override
    public CategoryExt getById(Integer id, boolean cascadeChildren) {
      Category category= categoryMapper.selectById(id);
      CategoryExt categoryExt=CategoryExt.toExt(category);
        return categoryExt;
    }

    @Override
    public List<CategoryExt> list(String type, boolean cascadeChildren) {
       LambdaQueryWrapper<Category> lqw = new LambdaQueryWrapper();
       if(type.equals("parent")){
           lqw.isNull(Category::getParentId);
       }else if(type.equals("chile")){
           lqw.isNotNull(Category::getParentId);
       }
        List<Category> categories = categoryMapper.selectList(lqw);

        return CategoryExt.toExt(categories);
    }

    @Override
    public IPage<CategoryExt> pageQueryByClause(IPage<Category> page, CategoryExt categoryExt) {
        Integer parentId = categoryExt.getParentId();
        LambdaQueryWrapper<Category> lqw=new LambdaQueryWrapper<>();
        lqw.eq(parentId!=null, Category::getParentId,parentId);
        categoryMapper.selectPage(page,lqw);
        return  PageUtil.convert(page,CategoryExt::toExt);
    }

    @Override
    public void upload(InputStream is) {

    }

    @Override
    public void download(OutputStream os) {

    }
}
